/*
 * @Author: 啊彪
 * @Date: 2021-08-25 19:52:21
 * @LastEditors: 啊彪
 * @LastEditTime: 2022-07-15 17:32:55
 * @Description: 奖励
 * @FilePath: \fkxzg\src\controller\reward.controller.ts
 */
import abiao_utils from "abiao_utils";
import { Code } from "../enum/code.enum";
import { FUNC_NAME, HANDLE_TYPE, PROP_NAME } from "../enum/itemLogs.enum";
import Equip from "../models/equip/equip.model";
import Hero from "../models/hero/hero.model";
import HeroFrag from "../models/hero/heroFrag.model";
import ConsDiamond from "../models/log/consdiamond.model";
import Integral from "../models/task/integral.model";
import User from "../models/user/user.model";
import bigNumber from "../utils/bigNumber";
import Result from "../utils/result";
import utils from "../utils/utils";
import equip from "./equip.controller";
import item from "./item.controller";
import statistics from "./statistics.controller";
import user from "./user.contorller";


export default class reward {

    // 道具名称
    static propName = {
        goldCoin: 'goldCoin', // 金币
        diamond: 'diamond', // 钻石
        hero: 'hero', // 英雄
        heroFrag: 'heroFrag',  // 英雄碎片
        exp: 'exp', // 经验
        equip: 'equip', // 装备
    }


    /**
     * 发送金币
     * @param roleId 角色ID
     * @param number 数量
     * @param desc 描述
     * @param func 功能
     */
    static async sendGoldCoin(roleId: number, number: number, desc: string, func: FUNC_NAME) {
        let userInfo: any = await user.getUserInfo(roleId);

        let goldCoin: string = bigNumber.jia(Math.round(userInfo.goldCoin), Math.round(number));
        await User.updateOne({ roleId }, { goldCoin, updateTime: abiao_utils.date() });
        await statistics.total_add_goldCoin(roleId, userInfo.nickName, userInfo.serverId, number);
        await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.GOLDCOIN, number, desc, userInfo.goldCoin, goldCoin, func);
    }

    /**
     * 减少金币
     * @param roleId 角色ID
     * @param number 数量
     * @param desc 描述
     * @param func 功能
     */
    static async reduceGoldCoin(roleId: number, number: number, desc: string, func: FUNC_NAME) {
        let userInfo: any = await user.getUserInfo(roleId);

        let goldCoin: string = bigNumber.jian(Math.round(userInfo.goldCoin), Math.round(number));
        if (Number(goldCoin) < 0) {
            return -1
        }
        await User.updateOne({ roleId }, { goldCoin, updateTime: abiao_utils.date() });
        await statistics.total_reduce_goldCoin(roleId, userInfo.nickName, userInfo.serverId, number);
        await item.itemLogs(roleId, HANDLE_TYPE.REDUCE, PROP_NAME.GOLDCOIN, number, desc, userInfo.goldCoin, goldCoin, func);
    }

    /**
     * 发送钻石
     * @param roleId 角色ID
     * @param number 数量
     * @param desc 描述
     * @param func 功能
     */
    static async sendDiamond(roleId: number, number: number, desc: string, func: FUNC_NAME) {
        let userInfo: any = await user.getUserInfo(roleId);

        let diamond: string = bigNumber.jia(userInfo.diamond, number);
        await User.updateOne({ roleId }, { diamond, updateTime: abiao_utils.date() });
        await statistics.total_add_diamond(roleId, userInfo.nickName, userInfo.serverId, number);
        await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.DIAMOND, number, desc, userInfo.diamond, diamond, func);
    }
    /**
     * 减少钻石
     * @param roleId 角色ID
     * @param number 数量
     * @param desc 描述
     * @param func 功能
     */
    static async reduceDiamond(roleId: number, number: number, desc: string, func: FUNC_NAME) {
        let userInfo: any = await user.getUserInfo(roleId);

        let diamond: string = bigNumber.jian(userInfo.diamond, number);
        if (Number(diamond) < 0) {
            return -1
        }
        await User.updateOne({ roleId }, { diamond, updateTime: abiao_utils.date() });
        await statistics.total_reduce_diamond(roleId, userInfo.nickName, userInfo.serverId, number);
        await item.itemLogs(roleId, HANDLE_TYPE.REDUCE, PROP_NAME.DIAMOND, number, desc, userInfo.diamond, diamond, func);
    }


    /**
     * 发送武将
     * @param roleId 角色ID
     * @param heroId 武将ID
     * @param desc 描述
     * @param func 功能
     */
    static async sendHero(roleId: number, heroId: number, desc: string, func: FUNC_NAME) {
        let id = heroId == -1 ? abiao_utils.getRandom(2001, 2028) : heroId;
        let HeroRes: any = await Hero.findOne({ roleId, id });
        if (!HeroRes) {
            let HeroData: any = await utils.get_id_json('hero/hero.json', id, 'id');
            let info = {
                roleId,
                id: HeroData.id,
                name: HeroData.name,
                isGoToWar: id == 2001 ? true : false,
                position: id == 2001 ? 0 : -1,
            }
            await Hero.create(info);
            await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.HERO, 0, `武将[${HeroData.name}(${info.id})] ${desc}`, 0, 1, func);
        } else {
            let item_heroId = id - 1000;
            let itemData: any = await utils.get_id_json('item.json', item_heroId, 'id');
            this.sendHeroFrag(roleId, heroId, itemData.composeNeed, `武将[${itemData.heroName}(${id})] ${desc}`, func);
        }
    }

    /**
    * 发送武将碎片
    * @param roleId 角色ID
    * @param heroId 武将ID
    * @param number 数量
    * @param desc 描述
    * @param func 功能
    */
    static async sendHeroFrag(roleId: number, heroId: number, number: number, desc: string, func: FUNC_NAME) {
        let id = heroId == -1 ? abiao_utils.getRandom(2001, 2028) : heroId;
        let HeroFragRes: any = await HeroFrag.findOne({ roleId, id });
        if (!HeroFragRes) {
            let item_heroId = id - 1000;
            let itemData: any = await utils.get_id_json('item.json', item_heroId, 'id');
            let info = {
                roleId,
                id,
                name: itemData.heroName,
                num: number,
            }
            await HeroFrag.create(info);
            await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.HERO_FRAG, number, `[${itemData.heroName}(${info.id})]  ${desc}`, 0, number, func);
        } else {
            let num = Number(HeroFragRes.num) + Number(number);
            await HeroFrag.updateOne({ roleId, id }, { num });
            await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.HERO_FRAG, number, `[${HeroFragRes.name}(${HeroFragRes.id})]  ${desc}`, HeroFragRes.num, num, func);
        }
        return id
    }

    /**
    * 发送装备
    * @param roleId 角色ID
    * @param equipId 装备ID
    * @param desc 描述
    * @param func 功能
    */
    static async sendEquip(roleId: number, equipId: number, desc: string, func: FUNC_NAME) {

        let randEquip: any
        if (equipId == -1) {
            let equipTzData: any = await utils.get_all_json('equip/equipment.json');
            randEquip = abiao_utils.getRandomArrayElements(equipTzData, 1)[0];
        }

        let id = equipId == -1 ? randEquip.id : equipId
        let equipData: any = await utils.get_id_json('equip/equipment.json', id, 'id');

        let info = {
            roleId,
            id: equipData.id,
            name: equipData.name,
            tzName: equipData.tzName,
            group: equipData.group,
            part: equipData.part,
            useLv: equipData.useLv,
            maxQhLv: equipData.maxQhLv,
            attributeType0: equipData.attributeType0,
            attributeNum0: abiao_utils.getRandom(equipData.attributeMin0, equipData.attributeMax0 + 1),
            attributeType1: equipData.attributeType0,
            attributeNum1: abiao_utils.getRandom(equipData.attributeMin1, equipData.attributeMax1 + 1),
            growUp: abiao_utils.getRandom(equipData.attributeMin0 / 10, equipData.attributeMax0 / 10),
            affix: []
        }

        let equipAffixPartJson: any = await utils.get_part_json('equip/affix.json', equipData.part, 'part');
        let equipAffixDefaultPartJson: any = await utils.get_part_json('equip/affix.json', 6, 'part');

        let affixJson: any = equipAffixPartJson.concat(equipAffixDefaultPartJson)
        let affix = []
        affix = abiao_utils.getRandomArrayElements(affixJson, 1);

        info.affix = affix

        let ret = await Equip.create(info);
        await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.EQUIP, 0, `${desc} [属性1]${info.attributeType0}(${info.attributeNum0}) [属性2]${info.attributeType1}(${info.attributeNum1}) [成长]${info.growUp}`, 0, 1, func);
        return ret
    }

    /**
   * 发送成就点
   * @param roleId 角色ID
   * @param number 数量
   * @param desc 描述
   * @param func 功能
   */
    static async sendIntegral(roleId: number, number: number, desc: string, func: FUNC_NAME) {
        let userInfo: any = await user.getUserInfo(roleId);

        let IntegralRes: any = await Integral.findOne({ roleId });

        if (!IntegralRes) {
            let info = {
                roleId,
                num: number
            }
            await Integral.create(info);
            await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.INTEGRAL, number, desc, 0, info.num, func);
        } else {
            let num = Number(bigNumber.jia(IntegralRes.num, number));

            await Integral.updateOne({ roleId }, { num });

            await item.itemLogs(roleId, HANDLE_TYPE.ADD, PROP_NAME.INTEGRAL, number, desc, IntegralRes.num, num, func);
        }
    }

    /**
    * 发送多种物品
    * @param roleId 角色ID
    * @param desc 描述
    * @param prop 道具物品 [{type:道具名称,num:道具数量,id:道具ID}]
    * @param func 功能
    */
    static async sendItem(roleId: number, desc: string, prop: any, func: FUNC_NAME) {
        for (const iterator of prop) {
            switch (iterator.type) {
                case reward.propName.goldCoin:
                    await this.sendGoldCoin(roleId, iterator.num, desc, func);
                    break;
                case reward.propName.diamond:
                    await this.sendDiamond(roleId, iterator.num, desc, func);
                    break;
                case reward.propName.hero:
                    await this.sendHero(roleId, iterator.id, desc, func);
                    break;
                case reward.propName.heroFrag:
                    await this.sendHeroFrag(roleId, iterator.id || 2001, iterator.num, desc, func);
                    break;
                case reward.propName.equip:
                    for (let i = 0; i < iterator.num; i++) {
                        await this.sendEquip(roleId, iterator.id, desc, func);
                    }
                default:
                    break;
            }
        }
    }
}
